home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
nihcl-30.lha
/
nihcl-3.0
/
lib
/
Scheduler.h
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-19
|
5KB
|
144 lines
#ifndef SCHEDULER_H
#define SCHEDULER_H
/*$Header: /afs/alw.nih.gov/unix/sun4_40c/usr/local/src/nihcl-3.0/share/lib/RCS/Scheduler.h,v 3.0 90/05/20 00:21:06 kgorlen Rel $*/
/* Scheduler.h -- declarations for the Process Scheduler
THIS SOFTWARE FITS THE DESCRIPTION IN THE U.S. COPYRIGHT ACT OF A
"UNITED STATES GOVERNMENT WORK". IT WAS WRITTEN AS A PART OF THE
AUTHOR'S OFFICIAL DUTIES AS A GOVERNMENT EMPLOYEE. THIS MEANS IT
CANNOT BE COPYRIGHTED. THIS SOFTWARE IS FREELY AVAILABLE TO THE
PUBLIC FOR USE WITHOUT A COPYRIGHT NOTICE, AND THERE ARE NO
RESTRICTIONS ON ITS USE, NOW OR SUBSEQUENTLY.
Author:
K. E. Gorlen
Computer Systems Laboratory, DCRT
National Institutes of Health
Bethesda, MD 20892
$Log: Scheduler.h,v $
* Revision 3.0 90/05/20 00:21:06 kgorlen
* Release for 1st edition.
*
*/
#include "LinkedList.h"
#include "StackProc.h"
#include "nihclconfig.h"
#ifdef HAVE_SELECT
#include <sys/time.h>
#endif
class HeapProc;
class Scheduler : public NIHCL {
public: // type definitions
enum setjmp_val { schedule_process=0, resume_current_process, resume_new_process };
public: // static member functions
static unsigned char activePriority() { return active_process->priority(); }
static Process& activeProcess() { return *active_process; }
static bool astActive() { return ast_level != 0; }
static const char* className();
static void dumpOn(ostream& strm =cerr);
#ifndef NESTED_TYPES
static void initialize(stackTy* bottom, int priority =0);
#else
static void initialize(Process::stackTy* bottom, int priority =0);
#endif
static void printOn(ostream& strm =cout);
static void terminateActive() { activeProcess().terminate(); }
static void schedule();
static void yield();
public: // static member variables
static JMP_BUF switcher; // environment for stack switcher
// The following must be public so they can be accessed from the MAIN_PROCESS macro
static Process* active_process;
static StackProc* main_stack_process;
#ifndef NESTED_TYPES
static stackTy* main_stack_bottom;
#else
static Process::stackTy* main_stack_bottom;
#endif
private: // static member variables
static Process* previous_process;
static unsigned runCount; // total # of runnable processes
static LinkedList runList[MAXPRIORITY+1];
#ifdef HAVE_SELECT
static LinkedList selectList; // Process waiting for select
static struct timeval selectTimeout; // timeout on select
static int selectfd(); // do select(2) system call
void timeOutSelect() { selectTimeout.tv_sec = selectTimeout.tv_usec = 0; }
#endif
protected: // static member variables
static int ast_level; // AST nesting level
Scheduler() {} // to prevent construction of instances
private: // member functions
Scheduler(const Scheduler&) {} // to prevent copy of instances
static void addProcess(Process& p);
friend Process;
friend StackProc::StackProc(stackTy* bottom, int priority);
friend void StackProc::switchFrom(HeapProc*);
friend void StackProc::switchFrom(StackProc*);
};
#ifndef NESTED_TYPES
inline void Scheduler::initialize(stackTy* bottom, int priority)
#else
inline void Scheduler::initialize(Process::stackTy* bottom, int priority)
#endif
{
Scheduler::main_stack_bottom = bottom;
// Create MAIN process
Scheduler::active_process = new StackProc(bottom,priority);
}
/*
main() must call MAIN_PROCESS first thing to initialize the scheduler.
Note: MAIN_PROCESS must avoid using blocks in code executed as the
result of a longjmp() because such blocks may contain
compiler-generated local variables that share storage with local
variables used elsewhere in main(). Executing such a block after a
longjmp() would cause these local variables to be overwritten. Inline
functions must be avoided for the same reason.
*/
#ifndef NESTED_TYPES
#define _STACKTY stackTy
#else
#define _STACKTY Process::stackTy
#endif
#if STACK_GROWS_DOWN
#define _STACKPROC_ALLOCATE(active) \
alloca((Scheduler::main_stack_bottom - (active)->stack_top) * sizeof(_STACKTY)) \
#else
#define _STACKPROC_ALLOCATE(active) \
alloca(((active)->stack_top - Scheduler::main_stack_bottom) * sizeof(_STACKTY)) \
#endif
#define MAIN_PROCESS(priority) \
if (_SETJMP(Scheduler::switcher) == 0) goto _begin_main_process; \
/* longjmp() here to restore a process's stack */ \
((StackProc*)Scheduler::active_process)-> \
restoreStack((_STACKTY*)_STACKPROC_ALLOCATE((StackProc*)Scheduler::active_process)); \
_begin_main_process: \
Scheduler::initialize((_STACKTY*)alloca(sizeof(_STACKTY)),priority); \
class AST_LEVEL : public Scheduler {
public:
AST_LEVEL() { ast_level++; }
~AST_LEVEL() { ast_level--; }
};
// AST/signal handlers must begin with an AST_ENTER
#define AST_ENTER AST_LEVEL ast_level_dummy
#endif